package com.example.usbhidtool.hid

import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.hardware.usb.*
import android.util.Log
import android.util.LogPrinter
import com.example.usbhidtool.HidPageActivity
import com.example.usbhidtool.hid.umessage.UMessage
import com.example.usbhidtool.hid.umessage.UMessageWithCallBack

/**
 * USB设备管理
 */
class HidDeviceManager(val context: Context) {

    companion object {
        val VID = 1317
        val PID = 42156

//        val VID = 7994
//        val PID = 61416
        val CHIP = "良机来也"
    }

    private val usbManager: UsbManager
    private var deviceA: UsbDevice? = null
    private var connectionA: UsbDeviceConnection? = null
    private var interfaceA: UsbInterface? = null
    private var epOut: UsbEndpoint? = null
    private var epIn: UsbEndpoint? = null

    //日志输出器
    private var logWriter: ((String) -> Unit)? = null

    init {
        usbManager = context.getSystemService(Context.USB_SERVICE) as UsbManager
    }

    fun getInPoint(): UsbEndpoint? {
        return epIn
    }

    fun getConnection(): UsbDeviceConnection? {
        return connectionA
    }

    //设置日志输出器
    fun setLogPrinter(logWriter: (String) -> Unit) {
        this.logWriter = logWriter
    }

    /**
     * 找到USB设备,接收到设备连接广播后执行
     * 查找到后返回usbDevice对象，没找到返回null
     */
    fun findDevice(): UsbDevice? {
        deviceA = usbManager.deviceList.values.find {
            isMyDevice(it.vendorId, it.productId)
        }
        return deviceA
    }

    //是否是目标设备
    fun isMyDevice(vId: Int?, pID: Int?): Boolean {
        return vId == VID && pID == PID
    }

    /**
     * 检测是否有授权
     */
    fun checkPermission(): Boolean {
        if (deviceA == null) {
            logWriter?.invoke("还没有连接设备：deviceA==null")
            return false
        }
        return usbManager.hasPermission(deviceA)
    }

    /**
     * 打开连接，找到输入、输出端口
     */
    @Synchronized
    fun openConnection(): Boolean {
        logWriter?.invoke("准备打开连接")
        if (!checkPermission()) return false
        connectionA = usbManager.openDevice(deviceA)
        //获取接口A
        interfaceA = deviceA?.getInterface(0)
        if (connectionA?.claimInterface(interfaceA, true) == true) {
            //获取接口中输入输出端点
            val endPointCount = interfaceA?.endpointCount ?: 0
            logWriter?.invoke("endpointCount:$endPointCount")
            for (i in 0 until endPointCount) {
                val ep = interfaceA?.getEndpoint(i)
                if (ep?.type == UsbConstants.USB_ENDPOINT_XFER_BULK || ep?.type == UsbConstants.USB_ENDPOINT_XFER_INT) {
                    if (ep.direction == UsbConstants.USB_DIR_IN) {
                        epIn = ep
                        logWriter?.invoke("找到了入方向端点：" + ep.address)
                    } else {
                        epOut = ep
                        logWriter?.invoke("找到了出方向端点：" + ep.address)
                    }
                }
            }
            return epIn != null && epOut != null
        }
        return false
    }

    //请求USB授权
    fun requestPermission() {
        logWriter?.invoke("请求USB授权")
        val intent = PendingIntent.getBroadcast(context,
                0,
                Intent(HidPageActivity.Companion.ACTION_GRANT_USB), 0)
        usbManager.requestPermission(deviceA, intent)
    }

    //关闭USB总线A
    fun closeUsbPortA() {
        try {
            if (connectionA != null && connectionA?.serial !== "") {
                try {
                    //主线程延时50ms后才关闭
                    //Thread.sleep(50);
                    connectionA?.releaseInterface(interfaceA)
                    interfaceA = null
                    connectionA?.close()
                    connectionA = null
                    deviceA = null
                    epOut = null
                    epIn = null
                    logWriter?.invoke("closeUsbPortA==USB 设备已关闭!")
                } catch (ignored: Exception) {
                    ignored.printStackTrace()
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    //检查设备状态
    private fun checkDeviceStatus(): Boolean {
        if (interfaceA == null || connectionA == null) {
            return false
        }
        return true
    }

    /**
     * 写数据
     */
    fun bulkMessage(vararg msgList: UMessage, writeCallBack: (Boolean) -> Unit) {
        if (!checkDeviceStatus()) {
            logWriter?.invoke("==写数据_设备已断开==")
            writeCallBack.invoke(false)
            return
        }
        val size = msgList.size
        val toWrite = ByteArray(HidPageActivity.MAXPacketSize * size)
        for (i in 0 until size) {
            val uMessage = msgList[i]
            System.arraycopy(uMessage.data, 0, toWrite, i * HidPageActivity.MAXPacketSize, HidPageActivity.MAXPacketSize)
        }
        val ret: Int = connectionA!!.bulkTransfer(epOut, toWrite, toWrite.size, 0)
        if (ret > 0) {
            if (size == 1) {
                writeCallBack.invoke(true)
                val uMessage = msgList[0]
                if (uMessage is UMessageWithCallBack) {
                    uMessage.callBack.onComplete(1)
                }
            } else {
                //多个包，返回最后一个包返回成功
                val lastMessage = msgList[size - 1]
                if (lastMessage is UMessageWithCallBack) {
                    lastMessage.callBack.onComplete(1)
                }
            }
        } else {
            writeCallBack.invoke(false)
            logWriter?.invoke("====底层传输失败====ret:" + ret + ",length:" + toWrite.size)
        }
    }


}